Skip to content

Conversation

@eugeneepshteyn
Copy link
Contributor

@eugeneepshteyn eugeneepshteyn commented Jul 7, 2025

Enable creation of a temporary, when array section is passed to IGNORE_TKR dummy argument.

CallInterface::mustBeMadeContiguous() now returns "true" for IGNORE_TKR dummy args, when actual args are passed as array section. This triggers contiguity check already done in the caller and results in creation of a temporary.

If IGNORE_TKR includes c, then don't do contiguity check.

Step towards #138471

if (dummy->ignoreTKR.test(common::IgnoreTKR::Contiguous))
return false;

// TODO: should this check ignore "device" or "managed"?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewers, please answer this question

return HasVectorSubscriptHelper{}(expr);
}

// HasTriplet()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klausler , could you please review HasTriplet part? I'll add the other reviewers for lowering, once I add the test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply checking for triplets is going to give false positives. A(:) is contiguous when A is; so are A(J:K) and A(J:K:1). There's a general contiguity checking facility in Evaluate that can handle questions of contiguity; have you tried using it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If mustBeMadeContiguous() returns true, then this eventually gets to isSimplyContiguous() which is a helper function that calls Fortran::evaluate::IsSimplyContiguous().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And if mustBeMadeContiguous returns false, then IsSimplyContiguous is not called? Won't that lead to false negatives from e.g. A%X, non-CONTIGUOUS pointers, &c.?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would also be a problem with the current source, without my modifications. I'll check what happens in the cases you mentioned.

bool isIntentOut() const;
/// Does the argument have the CONTIGUOUS attribute or have explicit shape?
bool mustBeMadeContiguous() const;
bool mustBeMadeContiguous(const bool argHasTriplet = false) const;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const is never needed in a prototype argument that isn't a reference or a pointer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why "never"? Maybe I just want to make it obvious that the arg shouldn't be modified:

void f(const bool x = false)
{
  x = true;
}

$ clang++ -c const.cpp
const.cpp:3:5: error: cannot assign to variable 'x' with const-qualified type 'const bool'
    3 |   x = true;
      |   ~ ^
const.cpp:1:19: note: variable 'x' declared const here
    1 | void f(const bool x = false)
      |        ~~~~~~~~~~~^~~~~~~~~
1 error generated.

In any case, this is not important to my change, so I can remove it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prototype doesn't need the const here as part of the API, and the implementation is allowed to use const later if desired. So the const in the prototype makes me have to stop and wonder whether a & or * was intended but omitted.

return HasVectorSubscriptHelper{}(expr);
}

// HasTriplet()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simply checking for triplets is going to give false positives. A(:) is contiguous when A is; so are A(J:K) and A(J:K:1). There's a general contiguity checking facility in Evaluate that can handle questions of contiguity; have you tried using it?

@eugeneepshteyn eugeneepshteyn marked this pull request as ready for review July 9, 2025 20:12
Copy link
Contributor

@vzakhari vzakhari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the changes, Eugene! I have a couple of questions.

&characteristics->u);
if (!dummy)
return false;
if (dummy->ignoreTKR.test(common::IgnoreTKR::Contiguous))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes sense to me, but I am not sure about the code below.

return false;

// TODO: should this check ignore "device" or "managed"?
if (dummy->ignoreTKR.any() && argHasTriplet)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we care about whether the actual argument is an array section or not? Can it be a non-contiguous array (e.g. assumed shape dummy) that is passed as a dummy that is declared as IGNORE_TKR?

To fix #138471, can we return the following at line 1448?

return dummy->type.Rank() > 0 || dummy->ignoreTKR.test(common::IgnoreTKR::Rank);


subroutine s1()
!CHECK-LABEL: func.func @_QMtestPs1()
!CHECK: hlfir.copy_in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test fail withtout your change? It seems that mustBeMadeContiguous should already return true for this case. I am just trying to understand whether I missed something in the compiler code or that you added this test for completeness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what happens, when one oversimplifies the test. I will upload corrected test tomorrow.

@eugeneepshteyn
Copy link
Contributor Author

I'll be uploading a different PR, so closing this one.

@eugeneepshteyn eugeneepshteyn deleted the tkr-contiguous branch August 28, 2025 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants